﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Shell;
using VSSpeeder.Build;
using Microsoft.VisualStudio.Shell.Interop;

namespace VSSpeeder.Utils
{
	public class ErrorProvider : IServiceProvider
	{
		private readonly SolutionEventsListener _eventsListener;
		
		public ErrorListProvider ErrorListProvider;
		public List<ErrorTask> RegisteredTasks = new List<ErrorTask>();

		public ErrorProvider(SolutionEventsListener eventsListener)
		{
			_eventsListener = eventsListener;
			ErrorListProvider = new ErrorListProvider(this);
			ErrorListProvider.ProviderName = "Parallel Builds";
			ErrorListProvider.ProviderGuid = new Guid("A357201A-2AEF-4438-80B5-A97DD079232B");
			ErrorListProvider.Show();
		}


		public object GetService(Type serviceType)
		{
			return Microsoft.VisualStudio.Shell.Package.GetGlobalService(serviceType);
		}

		public void AddErrors(List<OutputTask> tasks)
		{
			//var errors = new List<Microsoft.VisualStudio.Shell.ErrorTask>();
			var solutionService = (IVsSolution)GetService(typeof(Microsoft.VisualStudio.Shell.Interop.IVsSolution));
			if (tasks.Count > 0)
			{
				uint totalProjects;
				solutionService.GetProjectFilesInSolution((uint) __VSGETPROJFILESFLAGS.GPFF_SKIPUNLOADEDPROJECTS, 0, null, out totalProjects);

				string[] projectNames = new string[totalProjects];
				solutionService.GetProjectFilesInSolution((uint)__VSGETPROJFILESFLAGS.GPFF_SKIPUNLOADEDPROJECTS, (uint)totalProjects, projectNames, out totalProjects);

			}
			foreach (var task in tasks)
			{
				IVsHierarchy projectHierarchy = null;
				//var projectName = Path.GetFileNameWithoutExtension(task.Project);

				// first try to find the project in the solution
				//_eventsListener._connect.ApplicationObject.Solution.Projects
				solutionService.GetProjectOfUniqueName(task.Project, out projectHierarchy);

				var error = new Microsoft.VisualStudio.Shell.ErrorTask()
				{
					ErrorCategory = task.TaskErrorCategory,
					Document = task.FileName,
					Line = task.Line,
					Column = task.Column,
					Text = task.Description,
					HierarchyItem = projectHierarchy
				};

				error.Navigate += new EventHandler(error_Navigate);
				RegisteredTasks.Add(error);
				ErrorListProvider.Tasks.Add(error);
			}
			//
		}

		void error_Navigate(object sender, EventArgs e)
		{
			var error = sender as ErrorTask;
			ErrorListProvider.Navigate(error, new Guid(EnvDTE.Constants.vsViewKindCode));
		}

		public void Clear()
		{
			foreach(var task in RegisteredTasks)
			{
				ErrorListProvider.Tasks.Remove(task);
			}
		}

        public void ShowErrorWindow()
        {
            // I really really want to show the error window ;-)
            ErrorListProvider.BringToFront();
            ErrorListProvider.Show();
            ErrorListProvider.ForceShowErrors();
        }


	}
}
